package com.trg.flex.dp
{
	import flash.events.Event;
	import flash.events.EventDispatcher;
	
	import mx.collections.ArrayCollection;
	import mx.collections.ICollectionView;
	import mx.collections.IViewCursor;
	import mx.collections.Sort;
	import mx.events.CollectionEvent;
	import mx.events.CollectionEventKind;

	public class DataProvider extends EventDispatcher implements ICollectionView
	{
		public static const TOTAL_RESULTS_CHANGED:String = "totalResultsChanged";
		public static const LOADING_CHANGED:String = "loadingChanged";
		
		public function DataProvider()
		{
			data.addEventListener(CollectionEvent.COLLECTION_CHANGE, relayEvent);
		}
		
		protected function relayEvent(event:Event):void {
			dispatchEvent(event);
		}
		
		protected var data:ArrayCollection = new ArrayCollection();
		protected var _resultsPerPage:int;
		protected var _page:int;
		protected var _sort:Sort;
		protected var _filterFunction:Function;
		protected var _loading:Boolean;
		
		protected function refreshData():Boolean {
			return true;
		}
		
		protected function refreshComplete(event:*=null):void {
			dispatchEvent(new CollectionEvent(CollectionEvent.COLLECTION_CHANGE, false, false, CollectionEventKind.REFRESH));
			_loading = false;
			dispatchEvent(new Event(LOADING_CHANGED));
		}
		

	//ICollectionView interface
		[Bindable(event="collectionChange")]
		public function get length():int
		{
			return data.length;
		}
		
		public function get filterFunction():Function
		{
			return _filterFunction;
		}
		
		public function set filterFunction(value:Function):void
		{
			_filterFunction = value;
		}
		
		public function get sort():Sort
		{
			return _sort;
		}
		
		public function set sort(value:Sort):void
		{
			if (!(value is NestedSort)) {
				value = new NestedSort(value);
			}
			_sort = value;
		}
		
		public function createCursor():IViewCursor
		{
			return new DataProviderCursor(this, data);
		}
		
		public function contains(item:Object):Boolean
		{
			return data.contains(item);
		}
		
		public function disableAutoUpdate():void
		{
			//TODO
		}
		
		public function enableAutoUpdate():void
		{
			//TODO
		}

		public function itemUpdated(item:Object, property:Object=null, oldValue:Object=null, newValue:Object=null):void
		{
			data.itemUpdated(item, property, oldValue, newValue);
		}
		
		public function refresh():Boolean
		{
			var result:Boolean = refreshData();
			if (result == false) {
				_loading = true;
				dispatchEvent(new Event(LOADING_CHANGED));
			}
			return result;
		}
		
		public function getItemAt(index:int):* {
			return data.getItemAt(index);
		}

		
	//PagedCollection interface		
		[Bindable]
		public function get resultsPerPage():int
		{
			return _resultsPerPage;
		}
		public function set resultsPerPage(value:int):void
		{
			_resultsPerPage = value;
		}
		
		[Bindable]
		public function get page():int
		{
			return _page;
		}
		public function set page(value:int):void
		{
			_page = value;
		}
		
		[Bindable(event="totalResultsChanged")]
		public function get totalResults():int
		{
			return 0;
		}
		
		[Bindable(event="totalResultsChanged")]
		public function get totalPages():int
		{
			if (resultsPerPage < 1 || totalResults == 0) return 1;
			return (totalResults - 1) / resultsPerPage + 1;
		}
		
		[Bindable(event="loadingChanged")]
		public function get loading():Boolean {
			return _loading;
		}
		
	}
}